package parse_swissprot;

require Exporter;


our @ISA = qw(Exporter);
our $VERSION = 1.00;
our @EXPORT = qw(parse_records);

use strict;
use warnings;

#_________________________________________________________________________________________

#	parse_records

#		Input:

#			$fh
#				reads sequence from <fh>

#			@fields to pass to the callback

#			$callback($$$$)
#				function to call with sequence and annotation info
#					takes 4 parameters:

#						$saved_fields	hash of array of saved lines
#										e.g. $saved_fields->{'SQ'}[0] = "ASDFASDFG"
# 						$recstart		the file position of the record
# 						$reccnt 		the count of parsed records
#						$data			see below

#			$data				called as $callback parameter
#									so that data can be stored if necessary

#_________________________________________________________________________________________
sub parse_records(*\@&$)
{
	my ($fh, $FIELDS_TO_SAVE, $callback, $data) = @_;

	my %FIELDS_TO_SAVE;
	@FIELDS_TO_SAVE{@$FIELDS_TO_SAVE} = ();
	my %saved_fields;
	my $reccnt = 0;
	my $recstart = 1;
	my $linecnt = 1;

	while(<$fh>)
	{
		++$linecnt;

		#skip empty lines
		next if $_ eq "\n";

		# call back after sequence line
		if (/^SQ/)
		{
			while (<$fh>)
			{
				++$linecnt;
				last if m[//];
				die "Fatal Error:\n".
					"Unexpected text on the sequence field on line $.:[$_]\n"
					unless /^\s+[A-Z ]+$/;
				tr/ \n//d;
				$saved_fields{'SQ'} .= $_;
			}
			chomp $saved_fields{'SQ'};
			
			# premature end of record: break logic
			last unless m[//];
			$callback->(	\%saved_fields,		 	# accession
							$recstart,				# the file position of the record
							++$reccnt, 				# the count of parsed records
							$data					# user call back
											);
			%saved_fields = ();
			$recstart = $linecnt;
		}
		
		# save other data fields if specified and of the right format
		else
		{
			die "Fatal Error:\n".
				"Unexpected text on line $. [$_]\n"
				unless /^([A-Z]{2})\s+(.*)\n/;
			push(@{$saved_fields{$1}}, $2)
				if (exists $FIELDS_TO_SAVE{$1});
		}
	}

	die "Fatal Error:\n".
		"Ended after $linecnt lines in the middle of a record.\n".
	    "The file should end with '\\' rather than \n[$_]\n"
		if (scalar keys %saved_fields);

	return $reccnt;
}






